/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
 *
 *           File:  enc8b10b.h
 *    Description:  8b10b encoder SystemC module
 *       
 *        Created:  12.02.2013 22:40:32
 *         Author:  Aleksey Golovchenko (lexgolovchenko@gmail.com)
 *   Organization:  St.Petersburg State Polytecnical Universisy
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifndef enc8b10b_h_
#define enc8b10b_h_

#include <systemc.h>

/*
 * Control input symbols
 */
#define DEC_K28D0 "00011100"	// K28.0
#define DEC_K28D1 "00111100"	// K28.1
#define DEC_K28D2 "01011100"	// K28.2
#define DEC_K28D3 "01111100"	// K28.3
#define DEC_K28D4 "10011100"	// K28.4
#define DEC_K28D5 "10111100"	// K28.5
#define DEC_K28D6 "11011100"	// K28.6
#define DEC_K28D7 "11111100"	// K28.7
#define DEC_K23D7 "11110111"	// K23.7
#define DEC_K27D7 "11111011"	// K27.7
#define DEC_K29D7 "11111101"	// K29.7
#define DEC_K30D7 "11111110"	// K30.7

/*
 * 8b10b encoder SystemC module
 */
SC_MODULE(enc8b10b)
{   
    // ------- Input ports -------------------
    sc_in<bool> clk;
    sc_in<bool> rd_reset;
    sc_in<bool> ctrl;
    sc_in<sc_uint<8> > data_in;

    // ------- Output ports ------------------
    sc_out<bool> rd_out;
    sc_out<sc_uint<10> > enc_out;

    // ------- Internal signals --------------
    sc_uint<11> m_enc;    
    sc_uint<10> m_idx;

    // ------- Encode table ------------------
    static const char m_encode_table[1024][12];

    SC_CTOR(enc8b10b) 
    {
        m_enc = 0;
        m_idx = 0;
        enc_out.initialize(0);        

        SC_METHOD(encode);
        sensitive << clk.pos();        
    }
 
    // ------- Encoding method ---------------
    void encode() 
    {
        // index for encode table - 10 bit vecor (CTRL_BIT, RD_INP, DATA_8_BIT)
        m_idx = (sc_uint<1>(ctrl.read()), sc_uint<1>((!rd_reset.read() && m_enc[10])), data_in);

        // get coded value from table
        m_enc = sc_uint<11>(sc_bv<11>(m_encode_table[m_idx.to_uint()]));        

        // write output ports
        enc_out.write(m_enc.range(9,0));
        rd_out.write(m_enc[10]);
    }    

};

#endif

